/*
 * @Author: 0x9DEFA478
 * @Date: 2024-07-19 21:44:39
 * @LastEditTime: 2024-09-16 00:57:48
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#ifndef hLL_H_TS_LL_H_
#define hLL_H_TS_LL_H_
#include "../API/H_TS_Config.h"
#include "./H_TS_LL_Core.h"




/**
 * 在这里包含需要的头文件
 */
#include "Peripheral.h"
// #include "stm32h7xx.h"
// #include "stm32f4xx.h"




//栈指针对齐 (影响队长大小与指针的对齐 对齐到sizeof(void*)*vH_TS_StackPtrAlign字节)
#define vH_TS_LL_StackPtrAlign                                    2

//栈标记值
#define vH_TS_LL_StackMarkValue                                   0x9DEFA478U

//编译顺序屏障 使得编译出的代码 在oH_TS_CompileBarrier()之前的代码执行完毕后才进行其之后的代码(防优化)
#if defined __ARMCC_VERSION
#define oH_TS_LL_CompileBarrier()                                 __schedule_barrier()
#elif defined __GNUC__
#define oH_TS_LL_CompileBarrier()                                 asm volatile("":::"memory")
#elif defined __ICCARM__
#define oH_TS_LL_CompileBarrier()                                 __asm volatile("":::"memory")
#else
#error "不支持的编译器"
#endif

//获取结构体成员偏移
#define cH_TS_LL_OffsetOfStructMember(in_Type,in_Member)          ((Husize)&((in_Type*)0)->in_Member)




//触发调度中断 屏蔽类型根据平台使用合适的屏蔽 
//这个操作需是可重入的(或者有应付重入的措施)
#define oH_TS_LL_CallScheduleISR()                                do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    SCB->ICSR=SCB_ICSR_PENDSVSET_Msk;\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)

//挂起任务调度
#define oH_TS_LL_SchedulerSuspend()                               do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    H_TS_LL_Core_Instance.SchedulerSuspend=-1;\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)


//恢复任务调度(线程用) 根据中断情况自动选择触发调度
#define oH_TS_LL_ResumeSchedulerAuto()                            do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    H_TS_LL_Core_Instance.SchedulerSuspend=0;\
                                                                    if(H_TS_LL_Core_Instance.SchedulerForISR!=0){\
                                                                      H_TS_LL_Core_Instance.SchedulerForISR=0;\
                                                                      oH_TS_LL_CallScheduleISR();\
                                                                    }\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)

//恢复任务调度(线程用) 并且固定触发一次调度
#define oH_TS_LL_ResumeSchedulerFixed()                           do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    H_TS_LL_Core_Instance.SchedulerSuspend=0;\
                                                                    H_TS_LL_Core_Instance.SchedulerForISR=0;\
                                                                    oH_TS_LL_CallScheduleISR();\
                                                                  }while(0)

//恢复任务调度(线程用) 根据in_IsFixed选择为oH_TS_LL_ResumeSchedulerAuto或者oH_TS_LL_ResumeSchedulerFixed
#define oH_TS_LL_ResumeSchedulerCondition(in_IsFixed)             do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    H_TS_LL_Core_Instance.SchedulerSuspend=0;\
                                                                    if(((in_IsFixed)!=0)||(H_TS_LL_Core_Instance.SchedulerForISR!=0)){\
                                                                      H_TS_LL_Core_Instance.SchedulerForISR=0;\
                                                                      oH_TS_LL_CallScheduleISR();\
                                                                    }\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)

//恢复调度并触发调度(线程使用) 并等待线程调度完成
#define oH_TS_LL_ResumeScheduler()                                do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    H_TS_LL_Core_Instance.ResumeSchedulerDone=-1;\
                                                                    oH_TS_LL_ResumeSchedulerFixed();\
                                                                    while(H_TS_LL_Core_Instance.ResumeSchedulerDone!=0){}\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)

//中断中触发线程中断
#define oH_TS_LL_ISR_CallScheduleISR()                            do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    if(H_TS_LL_Core_Instance.SchedulerSuspend!=0){\
                                                                      H_TS_LL_Core_Instance.SchedulerForISR=-1;\
                                                                    }else{\
                                                                      oH_TS_LL_CallScheduleISR();\
                                                                    }\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)




//挂起Tick
#define oH_TS_LL_TickSuspend()                                    do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    H_TS_LL_Core_Instance.SysTickSuspend=-1;\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)

//恢复Tick
#define oH_TS_LL_ReusmeTick()                                     do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    H_TS_LL_Core_Instance.SysTickSuspend=0;\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)

//线程调度时被调用(对于线程来说 相当于是调度后被调用)
#define oH_TS_LL_ResumeSchedulerDone()                            do{\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                    H_TS_LL_Core_Instance.ResumeSchedulerDone=0;\
                                                                    oH_TS_LL_CompileBarrier();\
                                                                  }while(0)




typedef struct{
  Hsize Priority;
  void* volatile* Stack;
  Hsize StackSize;
  int (*Code)(void*);
  void* v;
  const char* ThreadName;
}H_TS_LL_ThreadInitParam;

/**
 * @brief 初始化堆栈
 * @param Stack 堆栈内存首地址
 * @param StackSize 堆栈大小 单位: sizeof(void*)
 * @param Code 线程执行的代码
 * @param v 线程传入参数
 * @return 初始化好的堆栈指针
 */
void* H_TS_LL_ThreadStackInit(void* volatile* Stack,Hsize StackSize,int (*Code)(void*),void* v);

/**
 * @brief 初始化底层数据结构
 * @param v 空闲线程传入参数
 * @param IdleThreadStackSize 空闲线程堆栈大小
 * @return 0:成功 其他:内存申请失败
 */
int H_TS_LL_Init(void* v,Hsize IdleThreadStackSize);

/**
 * @brief 调度器启动
 *        启动Tick中断 调用该接口调用时已经允许Callback被调用
 *        为触发第一次调度中断做好准备
 *        在H_TS初始化完毕后 即将开始调度时被调用 
 * @param Callback Tick中断调用
 * @param v Callback的参数
 * @param SetTickCallback 设置Tick回调，用于设置Callback(v)为Tick中断调用并且使能Tick中断
 * @return 无
 */
void H_TS_LL_Start(void (*Callback)(void*),void* v,void (*SetTickCallback)(void (*)(void*),void*));

/**
 * @brief 构造H_TS_Thread
 * @param Thread 要构造的H_TS_Thread
 * @param ThreadInitParam 构造需要的相关参数
 * @return 无
 */
void H_TS_LL_ThreadInit(H_TS_Thread* Thread,const H_TS_LL_ThreadInitParam* ThreadInitParam);

/**
 * @brief 说明
 * @param Stack 堆栈内存首地址
 * @param StackSize 堆栈大小 单位: sizeof(void*)
 * @return 肯定未使用的大小 单位: sizeof(void*)
 */
Hsize H_TS_LL_ThreadStackGetFreeSize(void* volatile* Stack,Hsize StackSize);




#if vH_TS_IsEnableCPULoadCalculate != 0

typedef Hint32 H_TS_DeltaTime;
extern H_TS_DeltaTime H_TS_GetDT_LastT;

//每过多长时间更新一次CPU占用率 单位与H_TS_LL_GetDT获取的时间单位一致
//该值过大会降低更新频率 过小会降低精度 并且还要考虑H_TS_LL_GetDT的溢出速度
#define vH_TS_CPULoad_T                                           400000

/**
 * @brief 返回上次调用该函数是多少时间之前 该方法在使能CPU占用率统计后被使用
 * 根据平台修改
 * @param in_retVal 上次调用该函数是多少时间之前
 */
#define H_TS_LL_GetDT(in_retVal) \
do{\
  H_TS_DeltaTime t_H_TS_GetDT_nowT;\
  t_H_TS_GetDT_nowT=(H_TS_DeltaTime)TIM5->CNT;\
  in_retVal=t_H_TS_GetDT_nowT-H_TS_GetDT_LastT;\
  H_TS_GetDT_LastT=t_H_TS_GetDT_nowT;\
}while(0)

#endif




#endif //hLL_H_TS_LL_H_
